"""我们定义与会员相关的可靠性."""
from typing import Optional
from typing_extensions import Annotated

from fastapi import Body, Depends, HTTPException, Path, status

from core.models import Member

from api.settings import api_settings
from api.v1.auth import oauth2_optional, oauth2_scheme
from api.v1.auth.jwt import JWT
from api.v1.service.member import MemberServiceAPI, ValidateMemberAPI
from api.v1.models.auth import TokenPayload
from api.v1.models.member import CreateMember, UpdateMember
from lib.common import is_none_datetime
from lib.pbkdf2 import validate_password


async def get_current_member(
    token: Annotated[str, Depends(oauth2_scheme)],
    member_service: Annotated[MemberServiceAPI, Depends()]
) -> Member:
    """我们查找当前登录会员信息.

    Args:
        request (Request): Request 对象
        db (db_session): 数据库会话
        token (Annotated[str, Depends(oauth2_scheme)]): JWT

    Raises:
        HTTPException: 如果您没有成员的名称或没有成员信息，则会发生异常

    Returns:
        Member: 当前登录会员信息
    """
    payload: TokenPayload = JWT.decode_token(
        token,
        api_settings.ACCESS_TOKEN_SECRET_KEY
    )

    mb_id: str = payload.sub
    if mb_id is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Could not validate credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )

    member = member_service.get_member(mb_id)

    return member

'''
当你使用 Depends() 而不传入任何函数时，FastAPI 会尝试实例化该类型的类（在这里是 MemberServiceAPI）。
这种方式是为了方便你能够直接使用类，而不需要显式地定义每个依赖的提供函数。
确保 MemberServiceAPI 的构造函数及其依赖项都能被 FastAPI 正确解析，这样它才能正常工作。
'''
async def get_current_member_optional(
    token: Annotated[str, Depends(oauth2_optional)],
    member_service: Annotated[MemberServiceAPI, Depends()]
) -> Optional[Member]:
    """选择性查找当前登录成员信息.

    Args:
        token (Annotated[str, Depends(oauth2_scheme_none)]): JWT
        member_service (MemberServiceAPI): 会员服务Inston

    Returns:
        Optional[Member]: 当前登录会员信息或 None
    """
    if token is None:
        return None
    return await get_current_member(token, member_service)


def validate_create_data(
    validate: Annotated[ValidateMemberAPI, Depends()],
    data: CreateMember
):
    """加入时验证成员信息."""
    validate.valid_id(data.mb_id)
    validate.valid_name(data.mb_name)
    validate.valid_nickname(data.mb_nick)
    validate.valid_email(data.mb_email)
    validate.valid_recommend(data.mb_recommend, data.mb_id)

    return data


def validate_update_data(
    validate: Annotated[ValidateMemberAPI, Depends()],
    member: Annotated[Member, Depends(get_current_member)],
    data: UpdateMember,
):
    """验证固定的成员信息."""
    # 昵称更改验证
    if data.mb_nick and member.mb_nick != data.mb_nick:
        validate.valid_nickname(data.mb_nick)
        validate.valid_nickname_change_date(member.mb_nick_date)
    else:
        del data.mb_nick
        del data.mb_nick_date

    # 电子邮件更改验证
    if member.mb_email != data.mb_email:
        validate.valid_email(data.mb_email)

    # 成员信息公共变更验证
    if member.mb_open != data.mb_open:
        validate.valid_open_change_date(member.mb_open_date)
    else:
        del data.mb_open_date

    return data



def validate_certify_email_member(
    member_service: Annotated[MemberServiceAPI, Depends()],
    mb_id: Annotated[str, Path(..., title="会员Id", description="会员Id")],
    password: Annotated[str, Body(..., title="密码", description="会员密码")],
):
    """
    进行身份验证电子邮件更改时验证成员信息.
    """
    member = member_service.fetch_member_by_id(mb_id)
    if not validate_password(password, member.mb_password):
        raise HTTPException(
            status_code=400,
            detail="密码不正确.",
        )

    if not is_none_datetime(member.mb_email_certify):
        raise HTTPException(
            status_code=409,
            detail="这是一个已经完成邮件身份验证的成员.",
        )

    return member
